package com.xz.purchase.utils;

import com.xz.common.utils.StringUtils;
import com.xz.product.dto.AttributeParamDto;
import com.xz.purchase.domain.PurchaseProduct;
import com.xz.purchase.dto.PurchaseProductImportDto;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @program: erp-admin
 * @description:
 * @author: pengyuyan
 * @create: 2024-07-18 13:55
 **/

public class PurchaseImportUtil {

	/**
	 * 设置purchaseProduct对象的ProductParam字段值
	 *
	 * @param importDto       导入的dto数据
	 * @param purchaseProduct 采购入库的商品
	 * @param paramList       对应商品
	 * @param failInfo        失败信息
	 */
	public static void setProductParam(PurchaseProductImportDto importDto, PurchaseProduct purchaseProduct,
	                                   List<AttributeParamDto> paramList, StringBuilder failInfo) {
		Map<String, String> paramValMap = PurchaseImportUtil.getParamMap(importDto);

		// 检查多余的参数,避免用户在导入时，误以为录入的参数是存在于商品中。需要提示用户删除多余的参数值。
		PurchaseImportUtil.checkRedundantVal(paramValMap, paramList, failInfo);

		// paramList的size大于0，说明该商品时需要录入参数值的。
		if (paramList.size() > 0) {

			StringBuilder paramInfo = new StringBuilder();
			// 必须按返回的参数集合的顺序来迭代，否则会其他相同id的入库商品拼接的顺序不一致
			for (AttributeParamDto paramDto : paramList) {
				// 校验和拼接参数
				PurchaseImportUtil.checkAndAppendParam(
						paramDto.getAttributeName(),// 当前参数的名称
						paramValMap.get(paramDto.getAttributeName()),// 获取参数的名称对应（excel）导入值
						paramDto, // 参数组（用于校验参数的范围）
						paramInfo,
						failInfo
				);
			}
			// 赋值产品的参数
			purchaseProduct.setProductParam(paramInfo.toString());
		}
	}

	/**
	 * 构建参数与字段值映射的map
	 *
	 * @param importDto
	 * @return
	 */
	private static Map<String, String> getParamMap(PurchaseProductImportDto importDto) {
		Map<String, String> map = new HashMap<>();
		map.put("球镜", importDto.getParameterOne());
		map.put("柱镜", importDto.getParameterTwo());
		map.put("轴向", importDto.getParameterThree());
		map.put("眼别", importDto.getParameterFour());
		map.put("尺寸", importDto.getParameterFive());
		map.put("颜色", importDto.getParameterSix());
		map.put("其他", importDto.getParameterSeven());
		return map;
	}


	/**
	 * 检查多余的参数
	 *
	 * @param paramValMap 参数值map
	 * @param paramList   参数组数据（用于校验参数的范围）
	 * @param failInfo    失败信息
	 */
	private static void checkRedundantVal(Map<String, String> paramValMap, List<AttributeParamDto> paramList,
	                                      StringBuilder failInfo) {
		// 避免用户在导入时，误以为录入的参数是存在于商品中。需要提示用户删除多余的参数值。
		paramValMap.forEach((key, val) -> {
			// 如果该参数名在paramList找不到。说明用户录入多余的值。要提示用户去删掉
			if (StringUtils.isNotEmpty(val)) {
				Optional<AttributeParamDto> optional =
						paramList.stream().filter(s -> s.getAttributeName().equals(key)).findFirst();
				if (!optional.isPresent()) {
					// 否则记录异常
					failInfo.append(String.format("该商品无需录入%s参数值;\n", key));
				}
			}
		});
	}


	/**
	 * 检查参数
	 *
	 * @param parameterName 参数名称
	 * @param parameter     参数值
	 * @param paramDto      用于校验参数DTO对象
	 * @param paramInfo     参数拼接信息
	 * @param failInfo      失败信息
	 */
	private static void checkAndAppendParam(String parameterName, String parameter, AttributeParamDto paramDto,
	                                        StringBuilder paramInfo, StringBuilder failInfo) {

		if (StringUtils.isEmpty(parameter)) {
			failInfo.append(String.format("该商品需要录入%s参数;\n", parameterName, parameter));
			return;
		}

		List<String> attributeParameter = paramDto.getAttributeParameter();
		if (CollectionUtils.isEmpty(attributeParameter)) {
			// 如果参数组不存在，则说明无需校验是否在规定的范围内，直接追加新的参数
			paramInfo.append(String.format("%s：%s；", parameterName, parameter));
			return;
		}
		//attributeParameter.sort(String::compareTo);

		// 如果参数组存在，需要判断导入的参数值是否在规定的范围内
		Optional<String> optional = null;
		boolean isFlag;
		if (null == paramDto.getInputMode() || 2 == paramDto.getInputMode().intValue()) {
			optional = attributeParameter.stream().filter(s -> s.trim().equals(parameter.trim())).findFirst();
			isFlag = optional.isPresent();
		} else {
			try {
				BigDecimal parameterBig = new BigDecimal(parameter.trim());
				optional =
						attributeParameter.stream().filter(s -> 0 == new BigDecimal(s.trim()).compareTo(parameterBig)).findFirst();
				isFlag = optional.isPresent();
			} catch (Exception e) {
				// 记录异常
				failInfo.append(String.format("无效的%s参数值[%s];\n", parameterName, parameter));
				return;
			}
		}

		if (isFlag) {
			// 导入的参数值符合参数组规定的范围，则追加新的参数
			paramInfo.append(String.format("%s：%s；", parameterName, optional.get()));
		} else {
			// 否则记录异常
			failInfo.append(String.format("无效的%s参数值[%s];\n", parameterName, parameter));
		}
	}
}
